﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;
using System.IO;
using Word = Microsoft.Office.Interop.Word;

namespace docExplorer
{
    public partial class uc_Explorer : UserControl
    {
        #region Events

        public uc_Explorer()
        {
            InitializeComponent();
        }

        private void uc_Explorer_Load(object sender, EventArgs e)
        {
            this.TreeViewExplorerLoad();
        }

        private void tvwExplorer_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (((TreeNodeContents)e.Node.Tag).Type == TreeNodeType.Root)
                e.CancelEdit = true;
            else
            {
                /*foreach (TreeNode node in e.Node.Parent.Nodes)
                {
                    if (node.Text == e.Label)
                    {
                        e.CancelEdit = true;
                        break;
                    }
                }*/
                //if (!e.CancelEdit)
                //{
                    if (e.Label != null)
                    {
                        e.Node.Text = e.Label;
                        AddinUtils.TreeNodeSort(e.Node.Parent);
                        XMLUtils.ConstructXML(tvwExplorer.Nodes[0]);
                    }
                //}
            }
        }

        private void tvwExplorer_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            tvwExplorer.SelectedNode = e.Node;
        }

        private void tvwExplorer_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Type == TreeNodeType.Doc)
                AddinUtils.OpenDocument(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path);
        }

        private void tvwExplorer_AfterExpand(object sender, TreeViewEventArgs e)
        {
            e.Node.ContextMenuStrip = this.CreateContextMenuStrip(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Type, true);
        }

        private void tvwExplorer_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            e.Node.ContextMenuStrip = this.CreateContextMenuStrip(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Type, false);
        }

        private void tvwExplorer_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            tvwExplorer.SelectedNode = e.Node;
        }

        private void tvwExplorer_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            tvwExplorer.SelectedNode = e.Node;
        }

        #endregion

        #region Methods

        public void TreeViewExplorerLoad()
        {
            tvwExplorer.Nodes.Clear();
            TreeNode nodeRoot = new TreeNode("docExplorer", this.RetrieveTreeNodes());
            nodeRoot.Tag = new TreeNodeContents();
            nodeRoot.ContextMenuStrip = CreateContextMenuStrip(TreeNodeType.Root, false);
            tvwExplorer.Nodes.Add(AddinUtils.TreeViewSort(nodeRoot));
            tvwExplorer.SelectedNode = nodeRoot;
        }

        public ContextMenuStrip CreateContextMenuStrip(TreeNodeType nodeType, bool isExpanded)
        {
            ContextMenuStrip ctx = new ContextMenuStrip();
            if (!isExpanded)
            {
                ToolStripMenuItem tsmiExpandNode = new ToolStripMenuItem("Expand", null, this.ExpandNode);
                tsmiExpandNode.Font = new Font(tsmiExpandNode.Font.FontFamily, tsmiExpandNode.Font.Size, FontStyle.Bold);
                ctx.Items.Add(tsmiExpandNode);
                if (nodeType == TreeNodeType.Root)
                    ctx.Items[0].Text = "Expand All";
                else if (nodeType == TreeNodeType.Doc)
                    ctx.Items[0].Enabled = false;
            }
            else
            {
                ToolStripMenuItem tsmiCollapseNode = new ToolStripMenuItem("Collapse", null, this.CollapseNode);
                tsmiCollapseNode.Font = new Font(tsmiCollapseNode.Font.FontFamily, tsmiCollapseNode.Font.Size, FontStyle.Bold);
                if (nodeType != TreeNodeType.Category)
                    tsmiCollapseNode.Text = "Collapse All";
                ctx.Items.Add(tsmiCollapseNode);
            }
            ctx.Items.Add(new ToolStripSeparator());
            ToolStripMenuItem tsmiDeleteNode = new ToolStripMenuItem("Delete", null, this.DeleteTreeViewNode);
            ToolStripMenuItem tsmiRenameNode = new ToolStripMenuItem("Rename", null, this.RenameTreeViewNode);
            ToolStripMenuItem tsmiProperties = new ToolStripMenuItem("Properties", null, this.ViewProperties);
            switch (nodeType)
            {
                case TreeNodeType.Category:
                case TreeNodeType.Root:
                
                    ToolStripMenuItem tsmiCreateDocument = new ToolStripMenuItem("Create Document", null, this.CreateDoc);
                    ToolStripMenuItem tsmiCreateCategory = new ToolStripMenuItem("Create Category", null, this.CreateCategory);
                    ToolStripMenuItem tsmiImportDocs = new ToolStripMenuItem("Import Documents", null, this.ImportDocuments);

                    ctx.Items.Add(tsmiCreateDocument);
                    ctx.Items.Add(tsmiCreateCategory);
                    ctx.Items.Add(new ToolStripSeparator());
                    if (nodeType == TreeNodeType.Category)
                    {
                        ToolStripMenuItem tsmiAddTemplate = new ToolStripMenuItem("Add Template", null, this.AddTemplate);
                        ToolStripMenuItem tsmiAssociateFolder = new ToolStripMenuItem("Associte Folder", null, this.AssociateFolder);
                        ctx.Items.Add(tsmiAddTemplate);
                        ctx.Items.Add(tsmiAssociateFolder);
                        ctx.Items.Add(new ToolStripSeparator());
                    }
                    ctx.Items.Add(tsmiImportDocs);
                    ctx.Items.Add(new ToolStripSeparator());
                    ctx.Items.Add(tsmiDeleteNode);
                    ctx.Items.Add(tsmiRenameNode);
                    ctx.Items.Add(new ToolStripSeparator());
                    ctx.Items.Add(tsmiProperties);
                    break;
                case TreeNodeType.Doc:

                    ToolStripMenuItem tsmiOpenDoc = new ToolStripMenuItem("Open", null, this.OpenDocument);
                    tsmiOpenDoc.Font = new Font(tsmiOpenDoc.Font.FontFamily, tsmiOpenDoc.Font.Size, FontStyle.Bold);

                    ctx.Items.Add(tsmiOpenDoc);
                    ctx.Items.Add(new ToolStripSeparator());
                    ctx.Items.Add(tsmiDeleteNode);
                    ctx.Items.Add(tsmiRenameNode);
                    ctx.Items.Add(new ToolStripSeparator());
                    ctx.Items.Add(tsmiProperties);
                    break;
            }
            
            
            return ctx;
        }

        #region ContextMenusEvents

        private void ExpandNode(object sender, EventArgs e)
        {
            if (((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Type == TreeNodeType.Category)
                tvwExplorer.SelectedNode.Expand();
            else
                tvwExplorer.ExpandAll();
        }

        private void CollapseNode(object sender, EventArgs e)
        {
            if (((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Type == TreeNodeType.Category)
                tvwExplorer.SelectedNode.Collapse();
            else
                tvwExplorer.CollapseAll();
        }

        private void CreateDoc(object sender, EventArgs e)
        {
            tvwExplorer.SelectedNode.Expand();
            if ((((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path == null) ||
                    (((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path == string.Empty))
            {
                if (sfdDoc.ShowDialog() == DialogResult.OK)
                {
                    object template = Globals.ThisAddIn._missing;
                    if ((((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Template != null) &&
                        (((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Template != string.Empty))
                    {
                        template = ((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Template;
                        //File.Copy(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path, sfdDoc.FileName, true);
                        //AddinUtils.AbrirGuia(sfdDoc.FileName);
                    }
                    object miss = Globals.ThisAddIn._missing;
                    object filePath = sfdDoc.FileName;
                    Word._Document oDoc;
                    oDoc = Globals.ThisAddIn.Application.Documents.Add(ref template, ref miss, ref miss, ref miss);
                    oDoc.SaveAs(ref filePath, ref miss, ref miss, ref miss,
                                ref miss, ref miss, ref miss, ref miss, ref miss, ref miss,
                                ref miss, ref miss, ref miss, ref miss, ref miss, ref miss);

                    TreeNode newNodeDoc = new TreeNode(Path.GetFileNameWithoutExtension(sfdDoc.FileName));
                    newNodeDoc.Tag = new TreeNodeContents(sfdDoc.FileName);
                    tvwExplorer.SelectedNode.Nodes.Add(newNodeDoc);
                    tvwExplorer.SelectedNode = AddinUtils.TreeNodeSort(tvwExplorer.SelectedNode);
                    XMLUtils.ConstructXML(tvwExplorer.Nodes[0]);
                }
            }
            else
            {
                TreeNode newNodeDocument = new TreeNode("NewDocument");
                newNodeDocument.Tag = new TreeNodeContents(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path);
                newNodeDocument.SelectedImageIndex = 0;
                newNodeDocument.ImageIndex = 0;
                newNodeDocument.ContextMenuStrip = this.CreateContextMenuStrip(TreeNodeType.Doc, false);
                tvwExplorer.SelectedNode.Nodes.Add(newNodeDocument);
                newNodeDocument.BeginEdit();
            }
        }

        private void CreateCategory(object sender, EventArgs e)
        {
            tvwExplorer.SelectedNode.Expand();
            TreeNode newNodeCategory = new TreeNode("New Category");
            newNodeCategory.Tag = new TreeNodeContents("", "", DateTime.Now.ToString("dd/MM/yyyy"));
            newNodeCategory.SelectedImageIndex = 2;
            newNodeCategory.ImageIndex = 2;
            newNodeCategory.ContextMenuStrip = this.CreateContextMenuStrip(TreeNodeType.Category, false);
            tvwExplorer.SelectedNode.Nodes.Add(newNodeCategory);
            newNodeCategory.BeginEdit();
        }

        private void AddTemplate(object sender, EventArgs e)
        {
            if (sfdDoc.ShowDialog() == DialogResult.OK)
            {
                ((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Template = sfdDoc.FileName;
                XMLUtils.ConstructXML(tvwExplorer.Nodes[0]);
            }
        }

        private void AssociateFolder(object sender, EventArgs e)
        {
            if (fbdAssociate.ShowDialog() == DialogResult.OK)
            {
                ((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path = fbdAssociate.SelectedPath;
                XMLUtils.ConstructXML(tvwExplorer.Nodes[0]);
            }
        }

        private void OpenDocument(object sender, EventArgs e)
        {
            AddinUtils.OpenDocument(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path);
        }
        
        private void DeleteTreeViewNode(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you really delete this node and your childs?", "Alert!", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                tvwExplorer.SelectedNode.Parent.Nodes.Remove(tvwExplorer.SelectedNode);
                XMLUtils.ConstructXML(tvwExplorer.Nodes[0]);
            }
        }

        private void RenameTreeViewNode(object sender, EventArgs e)
        {
            tvwExplorer.SelectedNode.BeginEdit();
        }

        private void ImportDocuments(object sender, EventArgs e)
        {
            if (ofdImportDoc.ShowDialog() == DialogResult.OK)
            {
                foreach (string path in ofdImportDoc.FileNames)
                {
                    TreeNode newNodeDoc = new TreeNode(Path.GetFileNameWithoutExtension(path));
                    newNodeDoc.Tag = new TreeNodeContents(path);
                    tvwExplorer.SelectedNode.Nodes.Add(newNodeDoc);
                }
                XMLUtils.ConstructXML(tvwExplorer.Nodes[0]);
            }
        }

        private void ViewProperties(object sender, EventArgs e)
        {
            switch (((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Type)
            {
                case TreeNodeType.Root:
                    uc_RootProperties ucRootProp = new uc_RootProperties();
                    Globals.ThisAddIn.RootPropertiesCTP = Globals.ThisAddIn.CustomTaskPanes.Add(ucRootProp, "Properties of docExplorer");
                    Globals.ThisAddIn.RootPropertiesCTP.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
                    Globals.ThisAddIn.RootPropertiesCTP.Width = 300;
                    Globals.ThisAddIn.RootPropertiesCTP.Height = 370;
                    Globals.ThisAddIn.RootPropertiesCTP.Visible = true;
                    break;
                case TreeNodeType.Category:
                    string categoryName = tvwExplorer.SelectedNode.Text;
                    string template = ((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Template;
                    string createdCategory = ((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Create;
                    int nCategories = 0;
                    int nDocs = 0;
                    this.NumberOfChildNodes(tvwExplorer.SelectedNode.Nodes, ref nCategories, ref nDocs);
                    string localCategory = ((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path;
                    uc_CategoryProperties ucCategoryProp = new uc_CategoryProperties(categoryName, template, nCategories.ToString(), nDocs.ToString(), createdCategory, localCategory);
                    Globals.ThisAddIn.CategoryPropertiesCTP = Globals.ThisAddIn.CustomTaskPanes.Add(ucCategoryProp, "Properties of " + tvwExplorer.SelectedNode.Text);
                    Globals.ThisAddIn.CategoryPropertiesCTP.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
                    Globals.ThisAddIn.CategoryPropertiesCTP.Width = 315;
                    Globals.ThisAddIn.CategoryPropertiesCTP.Visible = true;
                    break;
                case TreeNodeType.Doc:
                    string name = Path.GetFileNameWithoutExtension(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path);
                    string category = string.Empty;
                    if (((TreeNodeContents)tvwExplorer.SelectedNode.Parent.Tag).Type == TreeNodeType.Root)
                        category = "Root";
                    else
                        category = tvwExplorer.SelectedNode.Parent.Text;
                    string created = File.GetCreationTime(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path).ToString("dd/MM/yyyy");
                    string local = Path.GetDirectoryName(((TreeNodeContents)tvwExplorer.SelectedNode.Tag).Path);
                    uc_DocProperties ucDocProp = new uc_DocProperties(name, category, created, local);
                    Globals.ThisAddIn.DocPropertiesCTP = Globals.ThisAddIn.CustomTaskPanes.Add(ucDocProp, "Properties of " + tvwExplorer.SelectedNode.Text);
                    Globals.ThisAddIn.DocPropertiesCTP.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
                    Globals.ThisAddIn.DocPropertiesCTP.Width = 290;
                    Globals.ThisAddIn.DocPropertiesCTP.Height = 340;
                    Globals.ThisAddIn.DocPropertiesCTP.Visible = true;
                    break;
            }
        }

        #endregion

        public TreeNode[] RetrieveTreeNodes()
        {
            IEnumerable<XElement> IEXRoot = XMLUtils.XExplorer.Elements();
            TreeNode[] childNodesRoot = new TreeNode[IEXRoot.Count()];
            int i = 0;
            foreach (var item in IEXRoot)
            {
                childNodesRoot[i] = new TreeNode(item.Name.LocalName, RetrieveTreeNodes(item));
                if (item.Attribute("type").Value == "Category")
                {
                    childNodesRoot[i].Tag = new TreeNodeContents(item.Attribute("path").Value, item.Attribute("template").Value, item.Attribute("create").Value);
                    childNodesRoot[i].ImageIndex = 2;
                    childNodesRoot[i].SelectedImageIndex = 2;
                }
                else
                {
                    childNodesRoot[i].Tag = new TreeNodeContents(item.Attribute("path").Value);
                    childNodesRoot[i].ImageIndex = 0;
                    childNodesRoot[i].SelectedImageIndex = 0;
                }
                    childNodesRoot[i].ContextMenuStrip = this.CreateContextMenuStrip(((TreeNodeContents)childNodesRoot[i].Tag).Type, false);
                i++;
            }

            return childNodesRoot;
        }

        private TreeNode[] RetrieveTreeNodes(XElement xElement)
        {
            IEnumerable<XElement> IEXChild = xElement.Elements();
            TreeNode[] childNodes = new TreeNode[IEXChild.Count()];
            int i = 0;
            foreach (var item in IEXChild)
            {
                childNodes[i] = new TreeNode(item.Name.LocalName, RetrieveTreeNodes(item));
                if (item.Attribute("type").Value == "Category")
                {
                    childNodes[i].Tag = new TreeNodeContents(item.Attribute("path").Value, item.Attribute("template").Value, item.Attribute("create").Value);
                    childNodes[i].ImageIndex = 2;
                    childNodes[i].SelectedImageIndex = 2;
                }
                else
                {
                    childNodes[i].Tag = new TreeNodeContents(item.Attribute("path").Value);
                    childNodes[i].ImageIndex = 0;
                    childNodes[i].SelectedImageIndex = 0;
                }
                childNodes[i].ContextMenuStrip = this.CreateContextMenuStrip(((TreeNodeContents)childNodes[i].Tag).Type, false);
                i++;
            }

            return childNodes;
        }

        private void NumberOfChildNodes(TreeNodeCollection nodes, ref int nCategories, ref int nDocs)
        {
            foreach (TreeNode childNodes in nodes)
            {
                if (((TreeNodeContents)childNodes.Tag).Type == TreeNodeType.Category)
                {
                    nCategories++;
                    NumberOfChildNodes(childNodes.Nodes, ref nCategories, ref nDocs);
                }
                else
                    nDocs++;
            }
        }

        #endregion

    }
}
